#include <stdio.h>
#include <iostream>
#include <cstring>
#include <math.h>
using namespace std;

typedef struct 
{
    int from, to;
    double weight;
}typenod;
typedef struct 
{
    double x,y;
}typedian;
    
typenod   tt[105];
typedian  nod[105];
double map[102][102];
int n;
double ans;
    
    
double countdis(double xx1, double yy1, double xx2, double yy2)
{
    return sqrt((xx1-xx2)*(xx1-xx2)+(yy1-yy2)*(yy1-yy2));
}    
 
void prim()
{
    int i, j, k; 
    int   pt;  // 存找到的最短边对应的数组下标 
    double min; // 存找到的最短边 

   	for (i=1; i<n; ++i)
   	{
   		tt[i].from = 1;
   		tt[i].to = i+1;
   		tt[i].weight = map[1][i+1];
    }  		

    for (k=1; k<n; ++k)  // n个点,找 N-1 次边 
    {
        min = tt[k].weight;
        pt = k;
        for (i=k+1; i<n; ++i)	// 找到一个最短边 
        	if (tt[i].weight < min)
        	{
        	    min = tt[i].weight;
        	    pt = i;
        	}    
        	
       	tt[0] = tt[k];		// 将它与第K边交换 
       	tt[k] = tt[pt];
       	tt[pt] = tt[0];
       	
       	j = tt[k].to; 
        for (i=k+1; i<n; ++i) // 对尚未加入树的 n-k 条边进行更新 
        	if ( tt[i].weight > map[j][tt[i].to])
        	{
        	 	tt[i].weight = map[j][tt[i].to];
           		tt[i].from = j;   
        	}    
    }        
}    

int main()
{
    int i, j, k, temp;
    
    cin >> n;
    for (i=1; i<=n; ++i)
    	cin >> nod[i].x >> nod[i].y;

   	for (i=1; i<=n; ++i)
   		for (j=i; j<=n; ++j)
   			map[i][j] = map[j][i] = countdis(nod[i].x, nod[i].y , nod[j].x, nod[j].y);
    prim();
    ans=0;
    for (i=1;i<n; ++i)
    	ans += tt[i].weight;
   	printf("%.2lf\n", ans);
    
        
    
    return 0;
}    